package com.study.thread.waitOrNotfy;
/*
    wait()方法：调用前需要获得监视器锁，也就是synchronized当前的这把锁，然后执行wait()会将当前锁释放掉，然后将当前线程进入阻塞状态(注1)
    //0、唤醒以后，线程不会立马执行，处于等待就绪状态，等待调度器分配cpu时间片（注01）调度
        //cpu分配的执行时间
    //1、wait(0)：无限阻塞，等待别人调用notify/notifyAll/intrrupt
    //2、notify：调用notify，有可能会在等待集合中将此线程唤醒（因为等待集合可能会有很多线程调用了这个监视器锁的wait()），所以只会随机选择一个
    //3、notifyAll：调用notifyAll会将当前监视器锁的等待集合中的所有等待线程进行唤醒
    //4、interrupt：会将线程中断，如果调用了wait则会抛出interruptError后，线程重新运行

    wait(timout)方法：调用前需要获得监视器锁，也就是synchronized当前的这把锁，然后执行wait(int)会将当前锁释放掉，然后将当前线程进入阻塞状态(注1)
    //1、wait(20000 )：也就是阻塞后，在20秒后唤醒线程
    //2、notify：调用notify，有可能会在等待集合中将此线程唤醒（因为等待集合可能会有很多线程调用了这个监视器锁的wait()），所以只会随机选择一个
    //3、notifyAll：调用notifyAll会将当前监视器锁的等待集合中的所有等待线程进行唤醒
    //4、interrupt：会将线程中断，如果调用了wait则会抛出interruptError后，线程重新运行
    //5、与sleep区别：sleep会睡眠，睡眠期间监视器锁会一直持有，wait()阻塞期间会把锁释放掉


    假设如果调用了多个object的wait()方法则只会释放掉调用的object的监视器锁（注1）
    //1、也就是说其余的获得过的Object锁不被释放，这样如果别的线程在等待的此线程已经获得的锁，则有可能死锁。

    //虚假唤醒：一个线程可以从挂起状态变为运行状态，即便没有被notify/notifyALL或被中断
        wait使用while检测条件因为假设有一条条件成立进入了wait()，如果是if的话，notify()时会继续跳过当前if执行后边的，所以要使用while一直检测是否满足执行条件
 */
public class WaitDemo1 {
    public static void main(String[] args) {
        Object obj = new Object();
        synchronized (obj){
            try {
                System.out.println("执行wait（）");
                obj.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("结束wait（）");
    }
}
